package com.ctg.itrdc.sysmgr.portal.service.impl;

import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.ctg.itrdc.pasp.context.service.BaseService;
import com.ctg.itrdc.sysmgr.portal.api.dto.FuncCompDTO;
import com.ctg.itrdc.sysmgr.portal.api.dto.FuncMenuDTO;
import com.ctg.itrdc.sysmgr.portal.api.dto.PrivilegeDTO;
import com.ctg.itrdc.sysmgr.portal.api.service.IPrivilegeService;
import com.ctg.itrdc.sysmgr.portal.common.constant.PrivGrantEnum.GrantSysobjType;
import com.ctg.itrdc.sysmgr.portal.data.IFuncCompDao;
import com.ctg.itrdc.sysmgr.portal.data.IFuncMenuDao;
import com.ctg.itrdc.sysmgr.portal.data.ISystemRolesDao;
import com.ctg.itrdc.sysmgr.portal.data.entity.FuncComp;
import com.ctg.itrdc.sysmgr.portal.data.entity.FuncMenu;
import com.ctg.itrdc.sysmgr.portal.data.entity.Privilege;
import com.ctg.itrdc.sysmgr.portal.data.vo.FuncCompVO;
import com.ctg.itrdc.sysmgr.portal.data.vo.FuncMenuVO;
import com.ctg.itrdc.sysmgr.portal.service.utils.BeanUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;

@Component("privilegeService")
public class PrivilegeServiceImpl extends BaseService<Privilege, Long, PrivilegeDTO>
		implements IPrivilegeService{

	protected Logger logger = LoggerFactory.getLogger(getClass());
	
	@Resource
	private ISystemRolesDao systemRolesDao;
	@Resource
	private IFuncMenuDao funcMenuDao;
	@Resource
	private IFuncCompDao funcCompDao;
	
	@Override
	public List<String> getPermissions(Long sysUserId,Long sysPostId){
		List<String> permissionList = Lists.newArrayList();
		addMenuPermissions(sysPostId, sysUserId, permissionList);
		addCompPermissions(sysPostId, sysUserId, permissionList);
		logger.debug("find Permissions from DB,param:sysUserId:{},sysPostId:{},result:{}",
				sysUserId,sysPostId, JSON.toJSONString(permissionList, true));
		return permissionList;
	}
	
	/**
	 * 添加菜单等权限
	 * 
	 * @param sysPostId
	 * @param sysUserId
	 * @param permissionList
	 */
	private void addMenuPermissions(Long sysPostId, Long sysUserId,
			List<String> permissionList) {
		List<FuncMenuDTO> resultList = selectMenuList(
				sysUserId, sysPostId,new FuncMenuDTO()); 
		if (CollectionUtils.isEmpty(resultList)) {
			return;
		}
		for (FuncMenuDTO funcMenuDTO : resultList) {
			String urlAddr = funcMenuDTO.getUrlAddr();
			if (StringUtils.isNotBlank(urlAddr))
				permissionList.add(urlAddr);
		}
	}

	/**
	 * 添加按钮等权限
	 * 
	 * @param sysPostId
	 * @param sysUserId
	 * @param permissionList
	 */
	private void addCompPermissions(Long sysPostId, Long sysUserId,
			List<String> permissionList) {
		List<FuncCompDTO> resultList = selectCompList(sysPostId, sysUserId,new FuncCompDTO());
		if (CollectionUtils.isEmpty(resultList)) {
			return;
		}
		for (FuncCompDTO compDTO : resultList) {
			String urlAddr = compDTO.getUrlAddr();
			if (StringUtils.isNotBlank(urlAddr))
				permissionList.add(urlAddr);
		}
	}
	
	
	private List<FuncMenuDTO> selectMenuList(Long sysUserId, Long sysPostId, FuncMenuDTO funcMenuDTO) {
		List<FuncMenuDTO> dtoList = Lists.newArrayList();
		List<FuncMenuDTO> sysUserMenu = selectMenuListBySysUserId(sysUserId, funcMenuDTO);
		List<FuncMenuDTO> sysPostMenu = selectMenuListBySysPostId(sysPostId, funcMenuDTO);
		if (CollectionUtils.isNotEmpty(sysUserMenu))
			dtoList.addAll(sysUserMenu);
		if (CollectionUtils.isNotEmpty(sysPostMenu))
			dtoList.addAll(sysPostMenu);
		return dtoList;
	}
	
	private List<FuncMenuDTO> selectMenuListBySysUserId(Long sysUserId, FuncMenuDTO dto) {
		Set<FuncMenuVO> entitySet = Sets.newHashSet();
		Long[] roleIds = systemRolesDao.selectRoleIdsBySysUserId(sysUserId);
		List<FuncMenuVO> sysRoleMenus = null;
		List<FuncMenuVO> sysUserMenus = null;
		FuncMenu entity = BeanUtils.applyIfNotException(dto, FuncMenu.class);
		if (roleIds != null && roleIds.length > 0) {
			sysRoleMenus = funcMenuDao.selectByIds(GrantSysobjType.SYSTEM_ROLE, entity, roleIds);
			entitySet.addAll(sysRoleMenus);
		}
		sysUserMenus = funcMenuDao.selectByIds(GrantSysobjType.SYSTEM_USER, entity, sysUserId);
		entitySet.addAll(sysUserMenus);
		return BeanUtils.copyListNotException(Lists.newArrayList(entitySet), FuncMenuDTO.class);
	}
	
	private List<FuncMenuDTO> selectMenuListBySysPostId(Long sysPostId, FuncMenuDTO dto) {
		List<FuncMenuVO> entityList = Lists.newArrayList();
		Long[] roleIds = systemRolesDao.selectRoleIdsBySysPostId(sysPostId);
		List<FuncMenuVO> sysRoleMenus = null;
		List<FuncMenuVO> sysPostMenus = null;
		FuncMenu entity = BeanUtils.applyIfNotException(dto, FuncMenu.class);
		if (roleIds != null && roleIds.length > 0) {
			sysRoleMenus = funcMenuDao.selectByIds(GrantSysobjType.SYSTEM_ROLE, entity, roleIds);
			entityList.addAll(sysRoleMenus);
		}
		sysPostMenus = funcMenuDao.selectByIds(GrantSysobjType.SYSTEM_POST, entity, sysPostId);
		entityList.addAll(sysPostMenus);
		return BeanUtils.copyListNotException(entityList, FuncMenuDTO.class);
	}

	
	private List<FuncCompDTO> selectCompList(Long sysPostId, Long sysUserId,FuncCompDTO funcCompDTO){
    	List<FuncCompDTO> dtoList = Lists.newArrayList();
		List<FuncCompDTO> sysUserComp = selectCompListBySysUserId(sysUserId,funcCompDTO);
		List<FuncCompDTO> sysPostComp = selectCompListBySysPostId(sysPostId,funcCompDTO);
		dtoList.addAll(sysUserComp);
		dtoList.addAll(sysPostComp);
    	return dtoList;
    }
	
	private List<FuncCompDTO> selectCompListBySysUserId(Long sysUserId,FuncCompDTO dto){
		FuncComp entity = BeanUtils.applyIfNotException(dto, FuncComp.class);
		List<FuncCompVO> entityList = Lists.newArrayList();
		Long[] roleIds = systemRolesDao.selectRoleIdsBySysUserId(sysUserId);
		List<FuncCompVO> sysRoleComps = funcCompDao.selectByIds(GrantSysobjType.SYSTEM_ROLE, entity,roleIds);
		List<FuncCompVO> sysUserComps = funcCompDao.selectByIds(GrantSysobjType.SYSTEM_USER, entity,sysUserId);
		entityList.addAll(sysRoleComps);
		entityList.addAll(sysUserComps);
		return BeanUtils.copyListNotException(entityList, FuncCompDTO.class);
	}
	
	private List<FuncCompDTO> selectCompListBySysPostId(Long sysPostId,FuncCompDTO dto){
		FuncComp entity = BeanUtils.applyIfNotException(dto, FuncComp.class);
		List<FuncCompVO> entityList = Lists.newArrayList();
		Long[] roleIds = systemRolesDao.selectRoleIdsBySysPostId(sysPostId);
		List<FuncCompVO> sysRoleComps = funcCompDao.selectByIds(GrantSysobjType.SYSTEM_ROLE,entity, roleIds);
		List<FuncCompVO> sysPostComps = funcCompDao.selectByIds(GrantSysobjType.SYSTEM_POST,entity, sysPostId);
		entityList.addAll(sysRoleComps);
		entityList.addAll(sysPostComps);
		return BeanUtils.copyListNotException(entityList, FuncCompDTO.class);
	}
	
}
